import logging
import re
import time
import random

from django.contrib.auth import authenticate
from django.core.cache import cache

from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework_simplejwt.tokens import RefreshToken

from home.views import logger
from users.models import Users

# Create your views here.

logger = logging.getLogger('apps')

class LoginView(APIView):

    def post(self, request):
        try:
            username = request.data.get('username')
            password = request.data.get('password')

            if username and password:
                user = authenticate(username=username, password=password)
                if user:
                    refresh = RefreshToken.for_user(user)
                    logger.info(f"用户{user.username}登录成功")
                    return Response({
                        "code":1,
                        "massage":"登录成功",
                        "data":{
                            "token":str(refresh.access_token),
                            'refresh':str(refresh),
                            'username':user.username,
                            'user_id':user.id
                        }
                    })
                else:
                    logger.error(f"用户{username}登录失败，账号或密码错误")
                    return Response({
                        "code":0,
                        "massage":"账号或密码错误"
                    })
            else:
                logger.error(f"用户{username}登录失败，账号或密码为空")
                return Response({
                    "code":0,
                    "massage":"账号或密码为空"
                })
        except Exception as e:
            logger.error(f"登录失败，失败原因{e}")
            return Response({
                "code":0,
                "massage":f"登录失败，失败原因{e}"
            })



"""
1.接收手机号
2.效验手机号是否合法
3.业务效验：
    判断手机号是否注册过，如果没有，提示code:0,message:手机号未注册
    检查是否在冷却期内
    如果在冷却期内，返回剩余时间
4.生成验证码：4位/6位
    缓存到redis(key:手机号, value:验证码)
    调用第三方的短信接口
    记录本次发送时间
"""
class SendSmsCodeView(APIView):
    def post(self, request):
        try:
            # 接收手机号
            phone = request.data.get("phone", "")
            scene = request.data.get("scene", "login")
            # 效验手机号是否合法
            # if not re.match(r"^1[3-9]\d{9}$", phone):
            #     return Response({
            #         "code": 0,
            #         "message": "请输入正确的手机号"
            #     })
            #               业务效验：
            #           判断手机号是否注册过
            if scene == "login":
                if not Users.objects.filter(phone=phone).exists():
                    return Response({
                        "code": 0,
                        "message": "手机号未注册"
                    })
            elif scene == "register":
                if Users.objects.filter(phone=phone).exists():
                    return Response({
                        "code": 0,
                        "message": "手机号已注册"
                    })
            #     检查是是否在冷却期内  找到上次存储的时间
            last_send_time_key = f"users:login:sms_last_send:{phone}"
            last_send_time = cache.get(last_send_time_key)
            # 获取当前时间
            now = time.time()
            # 如果在冷却期内，返回剩余时间
            if last_send_time and now - last_send_time < 30:
                remaining = int(30 - (now - last_send_time))
                return Response({
                    "code": 0,
                    "message": f"请在{remaining}秒后重试"
                })
            #     生成验证码
            sms_code = ''.join(random.choices("0123456789", k=6))
            # 缓存到redis(key:手机号, value:验证码)
            cache.set(f"users:login:sms_code:{phone}", sms_code, timeout=150)
            # 模拟第三方短信接口
            logger.info(f"向手机号{phone}发送验证码:{sms_code}")
            #     记录本次发送时间
            cache.set(last_send_time_key, now, timeout=30)
            return Response({
                "code": 1,
                "message": "发送成功"
            })
        except Exception as e:
            logger.error(f"发送短信失败，失败原因：{e}")
            return Response({
                "code": 0,
                "message": f"发送短信失败，失败原因：{e}"
            })

class MobileLoginView(APIView):
    def post(self, request):
        try:
            # 接收手机号
            phone = request.data.get("phone","")
            sms_code = request.data.get("code","")
            # 效验手机号是否合法
            # if not re.match(r"^1[3-9]\d{9}$", phone):
            #     return Response({
            #         "code": 0,
            #         "message": "请输入正确的手机号"
            #     })
            if not Users.objects.filter(phone=phone).exists():
                return Response({
                    "code": 0,
                    "message": "手机号未注册"
                })

            sms_code_key = f"users:login:sms_code:{phone}"
        #       效验验证码
            cached_code = cache.get(sms_code_key)
            if not cached_code:
                return Response({
                    "code": 0,
                    "message": "验证码已过期"
                })

            if cached_code != sms_code:
                return Response({
                    "code": 0,
                    "message": "验证码错误"
                })
        #     验证通过，清除验证码缓存
            cache.delete(sms_code_key)
            user = Users.objects.get(phone=phone)
        #       生成token
            refresh = RefreshToken.for_user(user)
            logger.info(f"用户{user.username}登录成功,手机号为{phone}")

            return Response({
                "code": 1,
                "message": "登录成功",
                "data": {
                    "token": str(refresh.access_token),
                    'refresh': str(refresh),
                    'username': user.username,
                    'user_id': user.id
                }
            })




        except Exception as e:
            logger.error(f"手机号登录失败，失败原因：{e}")
            return Response({
                "code": 0,
                "message": f"手机号登录失败，失败原因：{e}"
            })

class UserRegisterView(APIView):
    def post(self, request):
        try:
            # 1. 接收参数
            username = request.data.get("username")
            password = request.data.get("password")
            phone = request.data.get("phone")
            code = request.data.get("code")
            if not all([username, password, phone, code]):
                return Response({
                    "code": 0,
                    "message": "参数不完整"
                })
            # 验证手机号格式
            if not re.match(r"^1[3-9]\d{9}$", phone):
                return Response({
                    "code": 0,
                    "message": "手机号格式错误"
                })
            # 验证手机号是否重复
            if Users.objects.filter(phone=phone).exists():
                return Response({
                    "code": 0,
                    "message": "手机号已注册"
                })
            if len(password) < 6:
                return Response({
                    "code": 0,
                    "message": "密码长度不能小于6位"
                })
            if len(password) > 20:
                return Response({
                    "code": 0,
                    "message": "密码长度不能大于20位"
                })
            # 至少包含数字和字母
            if not re.search(r"[0-9]", password) or not re.search(r"[a-zA-Z]", password):
                return Response({
                    "code": 0,
                    "message": "密码至少包含数字和字母"
                })
                # 5:缓存到redis
            sms_code_key = f"users:login:sms_code:{phone}"
            #       效验验证码
            cached_code = cache.get(sms_code_key)
            if code != cached_code:
                return Response({
                    "code": 0,
                    "message": "验证码错误"
                })
            # 创建用户.(注册)
            user = Users.objects.create_user(
                username=username,
                password=password,
                phone=phone
            )
            cache.delete(sms_code_key)
            refresh = RefreshToken.for_user(user)
            return Response({
                "code": 1,
                "message": "注册成功",
                "data": {
                    "token": str(refresh.access_token),
                    "refresh_token": str(refresh),
                    "username": user.username,
                    "user_id": user.id,
                    "phone": user.phone
                }
            })
        except Exception as e:
            return Response({
                "code": 0,
                "message": "注册失败",
                "data": str(e)
            })









